View Javadoc

1   package org.apache.maven.surefire.common.junit3;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Constructor;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  import java.lang.reflect.Modifier;
26  import org.apache.maven.surefire.util.ReflectionUtils;
27  
28  public final class JUnit3Reflector
29  {
30      private static final String TEST_CASE = "junit.framework.Test";
31  
32      private static final String TEST_RESULT = "junit.framework.TestResult";
33  
34      private static final String TEST_LISTENER = "junit.framework.TestListener";
35  
36      private static final String TEST = "junit.framework.Test";
37  
38      private static final String ADD_LISTENER_METHOD = "addListener";
39  
40      private static final String RUN_METHOD = "run";
41  
42      private static final String TEST_SUITE = "junit.framework.TestSuite";
43  
44      private final Class[] interfacesImplementedByDynamicProxy;
45  
46      private final Class testResultClass;
47  
48      private final Method addListenerMethod;
49  
50      private final Method testInterfaceRunMethod;
51  
52      private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
53  
54      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
55  
56      private final Class testInterface;
57  
58      private final Class testCase;
59  
60      private final Constructor testsSuiteConstructor;
61  
62      public JUnit3Reflector( ClassLoader testClassLoader )
63      {
64          testResultClass = ReflectionUtils.tryLoadClass( testClassLoader, TEST_RESULT );
65          testCase = ReflectionUtils.tryLoadClass( testClassLoader, TEST_CASE );
66          testInterface = ReflectionUtils.tryLoadClass( testClassLoader, TEST );
67          interfacesImplementedByDynamicProxy =
68              new Class[]{ ReflectionUtils.tryLoadClass( testClassLoader, TEST_LISTENER ) };
69          Class[] constructorParamTypes = { Class.class };
70  
71          Class testSuite = ReflectionUtils.tryLoadClass( testClassLoader, TEST_SUITE );
72  
73          // The interface implemented by the dynamic proxy (TestListener), happens to be
74          // the same as the param types of TestResult.addTestListener
75          Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
76  
77          if ( isJUnit3Available() )
78          {
79              testsSuiteConstructor = ReflectionUtils.getConstructor( testSuite, constructorParamTypes );
80              addListenerMethod = tryGetMethod( testResultClass, ADD_LISTENER_METHOD, addListenerParamTypes );
81              testInterfaceRunMethod = getMethod( testInterface, RUN_METHOD, new Class[]{ testResultClass } );
82          }
83          else
84          {
85              testsSuiteConstructor = null;
86              addListenerMethod = null;
87              testInterfaceRunMethod = null;
88          }
89      }
90  
91      // Switch to reflectionutils when building with 2.7.2
92      private static Method tryGetMethod( Class clazz, String methodName, Class[] parameters )
93      {
94          try
95          {
96              return clazz.getMethod( methodName, parameters );
97          }
98          catch ( NoSuchMethodException e )
99          {
100             return null;
101         }
102     }
103 
104     private static Method getMethod( Class clazz, String methodName, Class[] parameters )
105     {
106         try
107         {
108             return clazz.getMethod( methodName, parameters );
109         }
110         catch ( NoSuchMethodException e )
111         {
112             throw new RuntimeException( "When finding method " + methodName, e );
113         }
114     }
115 
116 
117     public Object constructTestObject( Class testClass )
118         throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException
119     {
120         Object testObject = createInstanceFromSuiteMethod( testClass );
121 
122         if ( testObject == null && testCase.isAssignableFrom( testClass ) )
123         {
124             Object[] constructorParams = { testClass };
125 
126             testObject = testsSuiteConstructor.newInstance( constructorParams );
127         }
128 
129         if ( testObject == null )
130         {
131             Constructor testConstructor = getTestConstructor( testClass );
132 
133             if ( testConstructor.getParameterTypes().length == 0 )
134             {
135                 testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
136             }
137             else
138             {
139                 testObject = testConstructor.newInstance( testClass.getName() );
140             }
141         }
142         return testObject;
143     }
144 
145     private static Object createInstanceFromSuiteMethod( Class testClass )
146         throws IllegalAccessException, InvocationTargetException
147     {
148         Object testObject = null;
149         try
150         {
151             Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
152 
153             if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
154             {
155                 testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
156             }
157         }
158         catch ( NoSuchMethodException e )
159         {
160             // No suite method
161         }
162         return testObject;
163     }
164 
165     private static Constructor getTestConstructor( Class testClass )
166         throws NoSuchMethodException
167     {
168         Constructor constructor;
169         try
170         {
171             constructor = testClass.getConstructor( new Class[]{ String.class } );
172         }
173         catch ( NoSuchMethodException e )
174         {
175             constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );
176         }
177         return constructor;
178     }
179 
180     public Class[] getInterfacesImplementedByDynamicProxy()
181     {
182         return interfacesImplementedByDynamicProxy;
183     }
184 
185     public Class getTestResultClass()
186     {
187         return testResultClass;
188     }
189 
190     public Method getAddListenerMethod()
191     {
192         return addListenerMethod;
193     }
194 
195     public Method getTestInterfaceRunMethod()
196     {
197         return testInterfaceRunMethod;
198     }
199 
200     public Class getTestInterface()
201     {
202         return testInterface;
203     }
204 
205     public Method getRunMethod( Class testClass )
206     {
207         return getMethod( testClass, RUN_METHOD, new Class[]{ getTestResultClass() } );
208     }
209 
210     public boolean isJUnit3Available()
211     {
212         return testResultClass != null;
213     }
214 }